<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="${ctxPath}/layui/css/layui.css">
<link rel="stylesheet" href="${ctxPath}/material/css/main.css">
<link rel="stylesheet" href="${ctxPath}/material/css/normalize.css">
<link rel="stylesheet" href="${ctxPath}/material/css/htmleaf-demo.css">
<title>Wechat</title>
</head>
<style>
.se{
	font-size:20px!important;
	border-bottom:1px solid black!important;
}
.unse{
	color:black;
}
.layui-layim-min .layui-layer-content{
	height:40px!important;
}
body{
 color:black!important;
}
</style>
<body>
在线聊天系统1.0
<audio controls autoplay style="display:none;"></audio> 

<script id="showVideo" type="text/html">
好友：<video id="video2" style="height:250px;width:400px" autoplay></video>&nbsp;&nbsp;&nbsp;&nbsp;
我：<video id="video" style="height:110px;width:150px" autoplay></video>
</script>
</body>
<script src="${ctxPath}/resources/js/jquery-2.2.4.min.js"></script>
<script src="${ctxPath}/resources/js/sockjs.min.js"></script>
<script src="${ctxPath}/layui/layui.js"></script>
<script src="${ctxPath}/material/js/recorder.js"></script>
<script src='${ctxPath}/material/js/jquery.gradientify.min.js'></script>
<script>
$(function(){
	$("body").gradientify({
	    gradients: [
	        { start: [49,76,172], stop: [242,159,191] },
	        { start: [255,103,69], stop: [240,154,241] },
	        { start: [33,229,241], stop: [235,236,117] }
	    ]
		,fps:10
	});
});

var iceServer = {
	    "iceServers": [{
	        "url": "stun:stun.l.google.com:19302"
	    }]
};
	
var getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
var PeerConnection = (window.PeerConnection ||
        window.webkitPeerConnection00 || 
        window.webkitRTCPeerConnection || 
        window.mozRTCPeerConnection);
var socket = new WebSocket('${websocketAddr}');
var pc = new PeerConnection(iceServer);
var myId = '';
var toId = '';
var isCancel = 0;
var sstream=null;

var userinfo = new Object();
userinfo.id = '${session.USERINFO.id}';
userinfo.username='${session.USERINFO.username}';
userinfo.no = '${session.USERINFO.no}';
//如果检测到媒体流连接到本地，将其绑定到一个video标签上输出

pc.onclose = function(event){
	console.log('重新打开peer连接');
	pc = new PeerConnection(iceServer);
};

pc.onaddstream = function(event){
	var video2 = document.getElementById('video2');
	video2.src = window.URL.createObjectURL(event.stream);
};

pc.onicecandidate = function(event){
    socket.send(JSON.stringify({
        "type": "candidate",
        "mine": {
        	"id":myId,
            "content": event.candidate
        },
        "toFriend":{
        	"id":toId
        }
    }));
};

// 发送offer和answer的函数，发送本地session描述
var sendOfferFn = function(desc){
    pc.setLocalDescription(desc);
    socket.send(JSON.stringify({ 
        "type": "offer",
        "mine": {
        	"id":myId,
            "content": desc
        },
        "toFriend":{
        	"id":toId
        }
    }));
},
sendAnswerFn = function(desc){
    pc.setLocalDescription(desc);
    socket.send(JSON.stringify({ 
        "type": "answer",
        "mine": {
        	"id":myId,
            "content": desc
        },
        "toFriend":{
        	"id":toId
        }
    }));
};


	layui.use('layim', function(layim) {
		var layim = layui.layim;
		//基础配置
		layim.config({
			init : {
				url : '${ctxPath}/init/initInfo' //接口地址（返回的数据格式见下文）
				,
				type : 'post' //默认get，一般可不填
				,
				data : {id:userinfo.id}
			//额外参数
			}
			,maxLength:200
			,copyright:	true
			//获取群员接口（返回的数据格式见下文）
			,
			title : userinfo.username,
			members : {
				url : '${ctxPath}/group/findByGid' //接口地址（返回的数据格式见下文）
				,
				type : 'get' //默认get，一般可不填
				,
				data : {}
			//额外参数
			}

			//上传图片接口（返回的数据格式见下文）
			,
			uploadImage : {
				url : '${uploadAddr}/upload/uploadImg' //接口地址
				,
				type : 'post' //默认post
			}

			//上传文件接口（返回的数据格式见下文）
			,
			uploadFile : {
				url : '${uploadAddr}/upload/uploadFile' //接口地址
				,
				type : 'post' //默认post
			}
			//扩展工具栏，下文会做进一步介绍（如果无需扩展，剔除该项即可）
			,
			tool : [ {
				alias : 'uploadMedia' //工具别名
				,
				title : '上传视频' //工具名称
				,
				icon : '&#xe6ed;' //工具图标，参考图标文档
			} ,{
				alias : 'recorder' //工具别名
					,
					title : '录音' //工具名称
					,
					icon : '&#xe617;' //工具图标，参考图标文档
				}  ,{
					alias : 'videos' //工具别名
						,
						title : '视频' //工具名称
						,
						icon : '&#xe6fc;' //工具图标，参考图标文档
					}]
			,
			chatLog :  '${ctxPath}/direct/directChatRecord' //聊天记录页面地址，若不开启，剔除该项即可
			,
			msgbox: '${ctxPath}/direct/directMsgbox?id='+userinfo.id //消息盒子页面地址，若不开启，剔除该项即可   
				,
			find: '${ctxPath}/direct/directFind?id='+userinfo.id //发现页面地址，若不开启，剔除该项即可
				,
			initSkin:'2.jpg',
			voice:false
		});
		
		layim.on('tool(videos)', function(insert, send, obj){ //事件中的tool为固定字符，而code则为过滤器，对应的是工具别名（alias） 
			var a = obj.data.id;
			console.log(obj);
			if(obj.data.type=='group'){
				layer.open({ title: '提示',content: '群组中不能使用视频功能'});		
			}else{
				layer.open({
					  title: false
					  ,closeBtn:0
					  ,content: '<img src="${ctxPath}/img/timg.gif" height="50px" width="50px"/>正在等待对方答复'
					  ,shade:0.6
					  , btn: ['取消']
					  ,yes: function(index, layero){
						  	layer.close(index); //如果设定了yes回调，需进行手工关闭
						  	isCancel = 1;//取消视频请求
					  }
				}); 
				socket.send(JSON.stringify({ 
				        "type": "requestVideo",
				        "mine": {
				        	"id":userinfo.id,
				        },"toFriend":{
				        	"id":a
				        }
				 }));
			}	
		});
		
		layim.on('tool(uploadMedia)', function(insert, send, obj){ //事件中的tool为固定字符，而code则为过滤器，对应的是工具别名（alias） 
			layer.open({
				  title: '上传视频/音频'		  
				  ,content: '<input type="file" id="uploadVideo" name="file" lay-type="video" class="layui-upload-file" />&nbsp;&nbsp;&nbsp;<input type="file" name="file"  id="uploadAudio" lay-type="audio" />'
			}); 
			layui.upload({
			    url: '${uploadAddr}/upload/uploadFile'
			    ,elem: '#uploadVideo' //指定原始元素，默认直接查找class="layui-upload-file"
			    ,method: 'POST' //上传接口的http类型
			    ,success: function(res){
			    	 layer.close(layer.index);
		 			 insert('video[' + res.data.src + ']'+res.data.name); //将内容插入到编辑器，主要由insert完成
		 			 send(); //自动发送
			    }
			  });
			layui.upload({
				    url: '${uploadAddr}/upload/uploadFile'	
				    ,elem: '#uploadAudio' //指定原始元素，默认直接查找class="layui-upload-file"
				    ,method: 'POST' //上传接口的http类型
				    ,success: function(res){
				    	 layer.close(layer.index);
			 			 insert('audio[' + res.data.src + ']'+res.data.name); //将内容插入到编辑器，主要由insert完成
			 			 send(); //自动发送
				    }
				  });
		});   
		
		layim.on('tool(recorder)', function(insert, send, obj){ //事件中的tool为固定字符，而code则为过滤器，对应的是工具别名（alias） 
			var recorder;  
			var audio = document.querySelector('audio');  
			HZRecorder.get(function (rec) {  
		        recorder = rec;  
		        recorder.start();  
		    });  
			layer.open({
				  title: '录音'		  
				  ,content: '<img src="${ctxPath}/img/timg.gif" height="50px" width="50px"/>正在录音,点击确定结束录音'
				  ,shade:0.6
				  , btn: ['取消', '发送']
				  ,closeBtn: 0
				  ,btn2: function(index, layero){
					  	layer.close(index); //如果设定了yes回调，需进行手工关闭
					    recorder.stop();  
					    var record = recorder.getBlob();  
					    var formData = new FormData();
					    formData.append("file", record);
					    $.ajax({
					        url : '${uploadAddr}/upload/uploadAudio',
					        data:formData,
					        processData: false,
					        contentType: false,
					        async : false,
					        type : "POST",
					        dataType : 'json',
					        success : function (res){
					 			 insert('audio[' + res.data.src + ']'); //将内容插入到编辑器，主要由insert完成
					 			 send(); //自动发送
					        }
					    });
				  }
				  ,yes: function(index, layero){
					  layer.close(index); //如果设定了yes回调，需进行手工关闭
					    recorder.stop();  
				}
			}); 
			
		}); 
		
		layim.on('ready', function(options){
			  console.log(options);
			  $.post('${ctxPath}/notify/getUnreadMsgNum', {
				 	uid: userinfo.id, //对方用户ID
		        }, function(res){
			  		layim.msgbox(res);
		       });
			  $('.layui-layim-user').click(function(){
					 layer.open({
						  type: 2, 
						  content: '${ctxPath}/direct/directUserInfo?id='+userinfo.id, //这里content是一个URL，如果你不想让iframe出现滚动条，你还可以content: ['http://sentsin.com', 'no']
							area: ['650px', '400px'],
							title: false
					 }); 
				});	
		});
		
		layim.on('chatChange', function(obj){
			console.log(obj);
			if(obj.data.type=='friend'){
				  var id = obj.data.id;	
				  $('.layim-chat-username').mouseover(function(){
					  $(this).addClass("se");
				  });
				  $('.layim-chat-username').mouseout(function(){
					  $(this).removeClass("se");
				  });
				  $('.layim-chat-username').click(function(){
					  layer.open({
						  type: 2, 
						  content: '${ctxPath}/direct/directUserInfo?id='+id, //这里content是一个URL，如果你不想让iframe出现滚动条，你还可以content: ['http://sentsin.com', 'no']
							area: ['650px', '400px'],
							title: false
					 }); 
				  });	
			}
		});
			     
		  //连接成功时触发
		  socket.onopen = function(){   
		  };  
		  //监听收到的消息
		  socket.onmessage = function(res){
			  var r = JSON.parse(res.data);
			  if(r.emit == 'friend'){
			    layim.getMessage(r.userMess); //res.data即你发送消息传递的数据（阅读：监听发送的消息）
			  }else if(r.emit == 'group'){
				  layim.getMessage(r.userMess); 
			  }else if(r.emit == 'status'){
				  if(r.userMess.type =='online'){
					  layim.setFriendStatus(r.userMess.id,'online' ); 
				  }else{
					  layim.setFriendStatus(r.userMess.id,'offline' ); 
				  }
			  }else if(r.emit == 'notifyDelFriend'){
					parent.layui.layim.removeList({
					type: 'friend' //或者group
					 ,id: r.userMess.fromid //好友或者群组ID
					});
			  }else if(r.emit=='notifyAddFriend'){
				  $.post('${ctxPath}/friend/addFriend', {
			        	id: r.userMess.id, //对方用户ID
			        	friendId: r.userMess.fromid
			        }, function(res){
			        	parent.layui.layim.addList(res);
			        	parent.layui.layim.setFriendStatus(res.id,res.status); 
			        });
			  }else if(r.emit=='notifyAddGroup'){
			        	parent.layui.layim.addList({
			        		  type: 'group' //列表类型，只支持friend和group两种
			        			  ,avatar: r.userMess.avatar //群组头像
			        			  ,groupname: r.userMess.username //群组名称
			        			  ,id: r.userMess.fromid //群组id
			        			});
			  }else if(r.emit=='notifyDelMember'){
					  parent.layui.layim.removeList({
						  type: 'group' //或者group
						  ,id: r.userMess.fromid //好友或者群组ID
						});
			  }else if(r.emit=='offer'){
				  var rr = JSON.parse(r.userMess.content);
				  console.log(rr);
					layer.open({
						  title: '视频聊天'	
						  ,closeBtn:0
						  ,shade:0.5
						  ,content: $('#showVideo').text()
						  ,area: ['700px', '400px']
						  ,btn: ['结束视频']
					 	  ,yes: function(index, layero){
					 		 socket.send( JSON.stringify({
								  type: 'cancelVideo' //随便定义，用于在服务端区分消息类型
									  ,mine: {"id":r.userMess.id},
									  toFriend:{"id":r.userMess.fromid}
							})); 
					 	  }
					}); 
				  getUserMedia.call(navigator, {
					    video: true,
					    audio: true
					}, function(stream) {
						console.log('绑定视频流');
					    //绑定本地媒体流到video标签用于输出
					    var video = document.getElementById('video');
					    video.src = window.URL.createObjectURL(stream);    
					    //向PeerConnection中加入需要发送的流
					    sstream = stream;
					    pc.addStream(stream);
	      				pc.setRemoteDescription(new RTCSessionDescription(rr));
					    pc.createAnswer(sendAnswerFn, function (error) {
		                       console.log('Failure callback: ' + error);
		                  });
					}, function(e) {
					    console.log('Reeeejected!', e);
					});
			  }else if(r.emit=='requestVideo'){
				  myId = r.userMess.id;
				  toId = r.userMess.fromid;
				  layer.confirm(toId+'向你视频发起视频请求', {
					  btn: ['接受', '拒绝', ] //可以无限个按钮
					}, function(index){
						 socket.send( JSON.stringify({
							  type: 'acceptVideo' //随便定义，用于在服务端区分消息类型
								  ,mine: {"id":r.userMess.id},
								  toFriend:{"id":r.userMess.fromid}
						})); 
						 layer.close(index);
					}, function(index){ 
						 socket.send( JSON.stringify({
							  type: 'refuseVideo' //随便定义，用于在服务端区分消息类型
								  ,mine: {"id":r.userMess.id},
								  toFriend:{"id":r.userMess.fromid}
						})); 
						 layer.close(index);
					});
			  }	else if(r.emit=='acceptVideo'){
				layer.close(layer.index);	
				myId = r.userMess.id;
				toId = r.userMess.fromid;
				layer.open({
					  title: '视频聊天'	
					  ,closeBtn:0
					  ,shade:0.5
					  ,content: $('#showVideo').text()
					  ,area: ['700px', '400px']
					  ,btn: ['结束视频']
				 	  ,yes: function(index, layero){
				 		 socket.send( JSON.stringify({
							  type: 'cancelVideo' //随便定义，用于在服务端区分消息类型
								  ,mine: {"id":r.userMess.id},
								  toFriend:{"id":r.userMess.fromid}
						})); 
				 	  }
				}); 
				getUserMedia.call(navigator, {
				    video: true,
				    audio: true
				}, function(stream) {
					console.log('绑定视频流');
				    //绑定本地媒体流到video标签用于输出
				    var video = document.getElementById('video');
				    video.src = window.URL.createObjectURL(stream);    
				    //向PeerConnection中加入需要发送的流
				    sstream = stream;
				    pc.addStream(stream);
				    //发送
				    pc.createOffer(sendOfferFn, function (error) {
				        console.log('Failure callback: ' + error);
				    });
				}, function(e) {
				    console.log('Reeeejected!', e);
				});
			  }else if(r.emit=='refuseVideo'){
				  layer.open({
					  title: '消息'
					  ,content: '对方拒绝了您的视频请求'
					});       
			  }else if(r.emit=='cancelVideo'){
				  	console.log('取消视频请求');
				    var videos = document.getElementsByTagName("video");
				    for (var i = 0; i < videos.length; i++) {
				      videos[i].pause();
				    }
				    location.reload();
				    layer.close(layer.index);
			  }
			  else if(r.emit=='answer'){
				  var rr = JSON.parse(r.userMess.content);
				  console.log('remoteDesc:'+rr);
				  pc.setRemoteDescription(new RTCSessionDescription(rr));
			  }
			  else if(r.emit=='candidate'){
				  if(r.userMess.content=='hello'){
					  
				  }else{
					  var rr = JSON.parse(r.userMess.content);
					  console.log('候选者: '+rr);
					  pc.addIceCandidate(new RTCIceCandidate(rr));
				  }
			  }	
			  else{
				  layim.getMessage(r.sysMess); //res.data即你发送消息传递的数据（阅读：监听发送的消息）
			  }		  
		  };
		
		  
		  layim.on('sendMessage', function(res){
			  console.log(res); 
			  if(res.to.type=='friend'){
				  socket.send( JSON.stringify({
					  type: 'friend' //随便定义，用于在服务端区分消息类型
						  ,mine: res.mine,
						  toFriend:res.to
				})); 
			  }else {
				  socket.send( JSON.stringify({
					  type: 'group' //随便定义，用于在服务端区分消息类型
						  ,mine: res.mine,
						  toGroup:res.to
				})); 
			  }
			});
			
			layim.on('online', function(status){
				location.reload();
				  console.log(status); //获得online或者hide
					socket.send( JSON.stringify({
						 type: 'changeStatus' //随便定义，用于在服务端区分消息类型
						,mine: {id:userinfo.id}
						,toFriend:{status:status}
					})); 
				});  
			
			layim.on('sign', function(value){
				  console.log(value); //获得新的签名
				  $.post({
					  url:"${ctxPath}/user/modtify",
					  data:{
						  no:userinfo.no,
						  sign:value
					  },
					  async:false
					  });
				});  
			
			
	});
	
	function send(res){
		socket.send(res); 
	};
	
	
	function showUserInfo(id){
		layer.open({
			  type: 2, 
			  content: '${ctxPath}/direct/directUserInfo?id='+id, //这里content是一个URL，如果你不想让iframe出现滚动条，你还可以content: ['http://sentsin.com', 'no']
				area: ['650px', '400px'],
				title: false
		 }); 
	}
	
	  
</script>
</html>